/**
 * Called by the Android System after an Android user was created.
 *
 * The HAL can use this property to create its equivalent user.
 *
 * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
 * must respond with a property change indicating whether the request succeeded or failed. If
 * it failed, the Android system will remove the user.
 *
 * The format of the request is defined by CreateUserRequest and the format of the response by
 * CreateUserResponse.
 *
 * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
 * created, the request would be:
 *
 * int32[0]: 42  // request id
 * int32[1]: 11  // Android id of the created user
 * int32[2]: 3   // Android flags (ephemeral guest) of the created user
 * int32[3]: 10  // current user
 * int32[4]: 0   // current user flags (none)
 * int32[5]: 3   // number of users
 * int32[6]: 0   // 1st user (user 0)
 * int32[7]: 0   // 1st user flags (none)
 * int32[8]: 10  // 2nd user (user 10)
 * int32[9]: 0   // 2nd user flags (none)
 * int32[19]: 11 // 3rd user (user 11)
 * int32[11]: 3  // 3rd user flags (ephemeral guest)
 * string: "ElGuesto" // name of the new user
 *
 * Then if the request succeeded, the HAL would return:
 *
 * int32[0]: 42  // request id
 * int32[1]: 1   // CreateUserStatus::SUCCESS
 *
 * But if it failed:
 *
 * int32[0]: 42  // request id
 * int32[1]: 2   // CreateUserStatus::FAILURE
 * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
 *                 // which in turn can take the proper action.
 *
 * @change_mode VehiclePropertyChangeMode:ON_CHANGE
 * @access VehiclePropertyAccess:READ_WRITE
 */

#include "PlatformProperty.h"
#include "UserHalHelper.h"

using namespace ecarx::vhal::core::property;
using namespace user_hal_helper;

static int findUnusedProfileId(Property& property) {
    int32_t newProfileId = INVALID_PROFILE_ID;
    std::vector<int32_t> createdProfileIds = property.getPlatformProfile()->getCreatedProfileIds();
    for (int i = 2; i <= 6; i++) { // profile_2/profile_3/profile_4/profile_5/profile_6这五个Profile分配给亲情用户使用
        if (std::find(createdProfileIds.begin(), createdProfileIds.end(), i) == createdProfileIds.end()) {
            newProfileId = i;
            break;
        }
    }
    return newProfileId;
}

SYSTEM_READ_WRITE_PROPERTY(CREATE_USER, MixedValue) {
    builder.area(VehicleArea::GLOBAL)
        .initValue([]() {
            MixedValue ret = {
                .int32Values = {0},
                .floatValues = {0.0f},
                .int64Values = {0},
                .bytes = {0x00},
                .stringValue = "CREATE_USER",
            };
            return ret;
        })
        .immutableStatus(PropertyStatus::Active)
        .withValueBySignals([](const MixedValue &value) {
            return value;
        })
        .onSetProperty([this](const MixedValue &value) {
            auto createUserRequest = toCreateUserRequest(value);
            if (!createUserRequest.ok()) {
                ALOGE("CREATE_USER: toCreateUserRequest failed: %s", createUserRequest.error().message().c_str());
                return;
            }
            if (createUserRequest->requestId == INVALID_REQUEST_ID) {
                ALOGE("CREATE_USER: createUserRequest requestId is invalid");
                return;
            }
            ALOGD("CREATE_USER: createUserRequest:= %s", toString(createUserRequest.value()).c_str());

            CreateUserResponse createUserResponse = {
                .requestId = createUserRequest->requestId,
                .status = CreateUserStatus::FAILURE,
            };

            std::string stringPidToUids = this->getPlatformProfile()->getAuxiliary()->getString(PROFILE_ID_TO_USER_ID, "");
            UserInfo newUserInfo = createUserRequest->newUserInfo;
            int cloneUserId = (int32_t)newUserInfo.flags >> 8;
            newUserInfo.flags = static_cast<UserFlags>((int32_t)newUserInfo.flags & 0xff);

            int profileId = INVALID_PROFILE_ID;
            if (isOwnerUser(newUserInfo)) { // 创建车主用户
                if (getUserId(stringPidToUids, OWNER_PROFILE_ID) != INVALID_USER_ID) { // 已有userId和profile_1映射
                    createUserResponse.errorMessage = "already have ADMIN user";
                    ALOGE("CREATE_USER: create user failed for userId=%d, already have admin user", newUserInfo.userId);
                } else {
                    this->getPlatformProfile()->createProfile(OWNER_PROFILE_ID);
                    profileId = OWNER_PROFILE_ID;
                    createUserResponse.status = CreateUserStatus::SUCCESS;
                }
            } else if (isEphemeralUser(newUserInfo)) { // 创建临时用户
                if (getUserId(stringPidToUids, EPHEMERAL_PROFILE_ID) != INVALID_USER_ID) { // 已有userId和profile_12映射
                    createUserResponse.errorMessage = "already have EPHEMERAL user";
                    ALOGE("CREATE_USER: create user failed for userId=%d, already have ephemeral user", newUserInfo.userId);
                } else {
                    profileId = EPHEMERAL_PROFILE_ID;
                    createUserResponse.status = CreateUserStatus::SUCCESS;
                }
            } else if (isGuestUser(newUserInfo)) { // 创建游客用户
                if (getUserId(stringPidToUids, GUEST_PROFILE_ID) != INVALID_USER_ID) { // 已有userId和profile_13映射
                    createUserResponse.errorMessage = "already have GUEST user";
                    ALOGE("CREATE_USER: create user failed for userId=%d, already have guest user", newUserInfo.userId);
                } else {
                    profileId = GUEST_PROFILE_ID;
                    createUserResponse.status = CreateUserStatus::SUCCESS;
                }
            } else if (isFamilyUser(newUserInfo)) { // 创建亲情用户
                int32_t newProfileId = findUnusedProfileId(*this);
                if (newProfileId == INVALID_PROFILE_ID) {
                    createUserResponse.errorMessage = "already have enough FAMILY user";
                    ALOGE("CREATE_USER: create user failed for userId=%d, already have enough family users", newUserInfo.userId);
                } else {
                    int cloneProfileId = getProfileId(stringPidToUids, cloneUserId);
                    this->getPlatformProfile()->createProfile(
                        newProfileId, (cloneProfileId != INVALID_PROFILE_ID) ? cloneProfileId : 0);
                    profileId = newProfileId;
                    createUserResponse.status = CreateUserStatus::SUCCESS;
                }
            } else { // 无效的用户标志位
                createUserResponse.errorMessage = "invalid flags user";
                ALOGE("CREATE_USER: create user failed for userId=%d, invalid userFlags", newUserInfo.userId);
            }

            if (profileId != INVALID_PROFILE_ID) {
                stringPidToUids = relationPidToUidsString(newUserInfo.userId, profileId, stringPidToUids);
            }
            this->getPlatformProfile()->getAuxiliary()->setString(PROFILE_ID_TO_USER_ID, stringPidToUids);
            this->getPlatformProfile()->getAuxiliary()->save();

            ALOGD("CREATE_USER: createUserResponse:= %s", toString(createUserResponse).c_str());
            setValue(static_cast<int32_t>(VehicleArea::GLOBAL), toVehiclePropValue(createUserResponse)->value);
        });
}